#ifndef CONNECTION_POOL_H
#define CONNECTION_POOL_H

#include <atomic>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <pqxx/pqxx>
#include <queue>
#include <string>

#include "Connection.h"

class ConnectionPool {
 public:
  //单例模式（必须支持C++11标准）
  static ConnectionPool &getConnectionPool(const std::string &dbname,
                                           const std::string &user,
                                           const std::string &password,
                                           const std::string &host,
                                           const std::string &port);
  //获取一个连接
  std::shared_ptr<Connection> getConnection();

 private:
  std::string dbname;       //数据库名
  std::string user;         //用户名
  std::string password;     //密码
  std::string host;         //地址
  std::string port;         //端口
  std::string connect_url;  //用于连接的url
  // TODO: 实现从配置中加载
  size_t initSize = 10;            //初始池内连接数量
  size_t maxSize = 1024;           //最大连接数量
  size_t maxIdleTime = 60;         //空闲连接等待回收时间，单位秒
  size_t connectionTimeout = 100;  //获取连接超时时间，单位毫秒

  //单生产者单消费者的队列，基于互斥量和条件变量实现
  std::queue<Connection *> connectionQueue;
  std::mutex queueMutex;
  std::condition_variable cv;
  size_t connectionCnt = 0;  //记录当前连接总数
  void produceConnection();  //生产者线程的函数
  void scanConnection();     //扫描队列，回收空闲连接
  ConnectionPool(const std::string &_dbname, const std::string &_user,
                 const std::string &_password, const std::string &_host,
                 const std::string &_port);
  //拷贝和拷贝赋值必须删除
  ConnectionPool(const ConnectionPool &) = delete;
  ConnectionPool &operator=(const ConnectionPool &) = delete;
};

#endif